LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;

USE WORK.TYPES.ALL;

package COMPONENTS is
    COMPONENT Ifetch
        PORT(    
				Instruct   : OUT INSTRUCTION;
            PC_plus_4_out   : OUT MEMADDR;
            Add_result      : IN  MEMADDR;
            Branch          : IN  STD_LOGIC;
            Zero            : IN  STD_LOGIC;
            PC_out          : OUT MEMADDR;
            clock,reset     : IN STD_LOGIC
        );
    END COMPONENT; 

    COMPONENT IF_ID
        PORT(
            clock,reset     : IN  STD_LOGIC;
            NextPc_in       : IN  MEMADDR;
            Instruct_in     : IN  INSTRUCTION;
            NextPc_out      : OUT MEMADDR;
            Instruct_out    : OUT INSTRUCTION
        );
    END COMPONENT;

    COMPONENT Idecode
        PORT(
            read_data_1         : OUT MEMDATA;
            read_data_2         : OUT MEMDATA;
            Instruct            : IN  INSTRUCTION;
            read_data           : IN  MEMDATA;
            ALU_result          : IN  MEMDATA;
            RegWrite, MemtoReg  : IN  STD_LOGIC;
            WrAddr              : IN  REGADDR;
            Sign_extend         : OUT MEMDATA;
            clock, reset        : IN  STD_LOGIC
        );
    END COMPONENT;

    COMPONENT control
        PORT(     
            Opcode     : IN STD_LOGIC_VECTOR( 5 DOWNTO 0 );
            RegDst     : OUT STD_LOGIC;
            ALUSrc     : OUT STD_LOGIC;
            MemtoReg   : OUT STD_LOGIC;
            RegWrite   : OUT STD_LOGIC;
            MemRead    : OUT STD_LOGIC;
            MemWrite   : OUT STD_LOGIC;
            Branch     : OUT STD_LOGIC;
            ALUop      : OUT STD_LOGIC_VECTOR( 1 DOWNTO 0 );
            clock, reset   : IN STD_LOGIC
        );
    END COMPONENT;

    COMPONENT ID_EX
        port(
            clock,reset : IN  STD_LOGIC;

            --Sinais de passagem
            NextPc_in   : IN  MEMADDR;
            NextPc_out  : OUT MEMADDR;

            --Sinais do controle:
            RegDst_in   : IN STD_LOGIC;
            ALUSrc_in   : IN STD_LOGIC;
            MemtoReg_in : IN STD_LOGIC;
            RegWrite_in : IN STD_LOGIC;
            MemRead_in  : IN STD_LOGIC;
            MemWrite_in : IN STD_LOGIC;
            Branch_in   : IN STD_LOGIC;
            ALUop_in    : IN STD_LOGIC_VECTOR( 1 DOWNTO 0 );

            ALUSrc_out   : OUT STD_LOGIC;
            MemtoReg_out : OUT STD_LOGIC;
            RegWrite_out : OUT STD_LOGIC;
            MemRead_out  : OUT STD_LOGIC;
            MemWrite_out : OUT STD_LOGIC;
            Branch_out   : OUT STD_LOGIC;
            ALUop_out    : OUT STD_LOGIC_VECTOR( 1 DOWNTO 0 );
    
            --Dados da decodificaÃ§Ã£o:
            read_data_1_in  : IN MEMDATA;
            read_data_2_in  : IN MEMDATA;
            Sign_extend_in  : IN MEMDATA;
    
            read_data_1_out : OUT MEMDATA;
            read_data_2_out : OUT MEMDATA;
            Sign_extend_out : OUT MEMDATA;
    
            --EndereÃ§o de escrita:
            WrAddr_0    : IN  REGADDR;
            WrAddr_1    : IN  REGADDR;
            WrAddr_out  : OUT REGADDR
        );
    END COMPONENT;

    COMPONENT  Execute
        PORT(    
            Read_data_1    : IN  MEMDATA;
            Read_data_2    : IN  MEMDATA;
            Sign_Extend    : IN  MEMDATA;
            Function_opcode: IN  STD_LOGIC_VECTOR( 5 DOWNTO 0 );
            ALUOp          : IN  STD_LOGIC_VECTOR( 1 DOWNTO 0 );
            ALUSrc         : IN  STD_LOGIC;
            Zero           : OUT STD_LOGIC;
            ALU_Result     : OUT MEMDATA;
            Add_Result     : OUT MEMADDR;
            PC_plus_4      : IN  MEMADDR;
            clock, reset   : IN  STD_LOGIC
        );
    END COMPONENT;


    COMPONENT EX_MEM
        port(
            clock,reset     : IN  STD_LOGIC;

            --Sinais de passagem
            Regwrite_in     : IN  STD_LOGIC;
            MemtoReg_in     : IN  STD_LOGIC;
            MemRead_in      : IN  STD_LOGIC;
            MemWrite_in     : IN  STD_LOGIC;
            Branch_in       : IN  STD_LOGIC;
            read_data_2_in  : IN  MEMDATA;
            Regwrite_out    : OUT STD_LOGIC;
            MemtoReg_out    : OUT STD_LOGIC;
            MemRead_out     : OUT STD_LOGIC;
            MemWrite_out    : OUT STD_LOGIC;
            Branch_out      : OUT STD_LOGIC;
            read_data_2_out : OUT MEMDATA;
    
            --Endereço
            Add_result_in   : IN  MEMADDR;
            WrAddr_in       : IN  REGADDR;
            Add_result_out  : OUT MEMADDR;
            WrAddr_out      : OUT REGADDR;
    
            --ULA
            Zero_in         : IN  STD_LOGIC;
            ALU_result_in   : IN  MEMDATA;
            Zero_out        : OUT STD_LOGIC;
            ALU_result_out  : OUT MEMDATA
        );
    END COMPONENT;

    COMPONENT dmemory
        PORT(   
            read_data           : OUT MEMDATA;
            address             : IN  MEMADDR;
            write_data          : IN  MEMDATA;
            MemRead, Memwrite   : IN  STD_LOGIC;
            Clock,reset         : IN  STD_LOGIC
        );
    END COMPONENT;

    COMPONENT MEM_WB
        port(
            clock, reset    : IN  STD_LOGIC;
            RegWrite_in     : IN  STD_LOGIC;
            MemtoReg_in     : IN  STD_LOGIC;
            ReadData_in     : IN  MEMDATA;
            ALU_result_in   : IN  MEMDATA;
            WrAddr_in       : IN  REGADDR;
            RegWrite_out    : OUT STD_LOGIC;
            MemtoReg_out    : OUT STD_LOGIC;
            ReadData_out    : OUT MEMDATA;
            ALU_result_out  : OUT MEMDATA;
            WrAddr_out      : OUT REGADDR
        );
    END COMPONENT;
END COMPONENTS;
